中间件
怎样自己写一个中间件?
比如有以下需求
- 通过该中间件去统计请求数目、状态和时间。
- 中间件把写过写回响应。
Server
server.go
package main
import
(
"net/http"
"strconv"
"sync"
"time"
"github.com/labstack/echo"
)
type
(
Stats struct{
Uptime time.Time `json:"uptime"`
RequestCount uint64 `json:"requestCount"`
Statuses map[string]int `json:"statuses"`
mutex sync.RWMutex
}
)
func NewStats()*Stats {
return &Stats{ Uptime: time.Now(), Statuses:make(map[string]int),}
}
// Process is the middleware function.
func(s *Stats) Process(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error{
if err := next(c); err !=nil{
c.Error(err)
}
s.mutex.Lock()
defer s.mutex.Unlock()
s.RequestCount++
status := strconv.Itoa(c.Response().Status)
s.Statuses[status]++
return nil
}
}
// Handle is the endpoint to get stats.
func(s *Stats) Handle(c echo.Context) error{
s.mutex.RLock()
defer s.mutex.RUnlock()
return c.JSON(http.StatusOK, s)
}
// ServerHeader middleware adds a `Server` header to the response.
func ServerHeader(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error{
c.Response().Header().Set(echo.HeaderServer, "Echo/3.0")
return next(c)
}
}
func main(){
e := echo.New()
// Debug mode
e.Debug =true
//-------------------
// Custom middleware
//-------------------
// Stats
s :=NewStats()
e.Use(s.Process)
e.GET("/stats", s.Handle)
// Endpoint to get stats
// Server header
e.Use(ServerHeader)
// Handler
e.GET("/",func(c echo.Context) error{
return c.String(http.StatusOK,"Hello, World!")
})
// Start server
e.Logger.Fatal(e.Start(":1323"))
}
响应
响应头
Content-Length:122
Content-Type:application/json; charset=utf-8
Date:Thu, 14 Apr 2016 20:31:46 GMT
Server:Echo/2.0
响应体
{
"uptime":"2016-04-14T13:28:48.486548936-07:00",
"requestCount":5,
"statuses":{
"200":4,
"404":1
}
}